package com.share.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
public class ImageUtil {
    private final static String DEFAULT_FONT = "宋体";
    private final static List<String> FONT_LIST = CollectionUtil.array2List(DEFAULT_FONT, "楷体", "微软雅黑", "仿宋", "黑体");

    /**
     * Linux和window上请安装对应的字体
     * 字体检测
     *
     * @param fontName
     * @return
     */
    private static String calcFontName(String fontName) {
        boolean contains = FONT_LIST.contains(fontName);
        if (!contains) {
            log.warn("找到不字体fontName={},Linux和window上请安装对应的字体,DEFAULT_FONT={}", fontName, DEFAULT_FONT);
            return DEFAULT_FONT;
        }
        return fontName;
    }

    //压缩图片
    public static BufferedImage reduceImage(BufferedImage image, int targetSizeByte) {
        BufferedImage newImage = null;
        int size = image2byte(image).length;
        if (targetSizeByte <= size) { //太小就不压缩
            double reduceRate = targetSizeByte * 1.0 / size;
            int height = (int) (image.getHeight() * reduceRate);
            int width = (int) (image.getWidth() * reduceRate);

            Image scaledInstance = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            newImage.createGraphics().drawImage(scaledInstance, 0, 0, null);
        } else {
            newImage = image;
        }
        return newImage;
    }

    public static Boolean merge2File(String imagePath1, String imagePath2, String outFilePath) throws Exception {
        return merge2File(imagePath1, imagePath2, new File(outFilePath));
    }

    public static Boolean merge2File(String imagePath1, String imagePath2, File outFile) throws Exception {
        String format = "jpg";
        String name = outFile.getName();
        if (name.endsWith(".png")) {
            format = "png";
        } else if (name.endsWith(".bpm")) {
            format = "bpm";
        }
        BufferedImage merge = merge(imagePath1, imagePath2);

        return ImageIO.write(merge, format, outFile);
    }

    public static BufferedImage merge(String imagePath1, String imagePath2) throws Exception {
        BufferedImage image1 = ImageIO.read(new File(imagePath1));
        BufferedImage image2 = ImageIO.read(new File(imagePath2));
        return merge(image1, image2, true);
    }

    public static byte[] addString(String imageFilePath, Map<String, String> kv) throws Exception {
        File file = new File(imageFilePath);
        return addString(file, kv);
    }

    public static byte[] addString(File imageFile, Map<String, String> kv) throws Exception {
        BufferedImage image = ImageIO.read(imageFile);
        return addString(image, kv);
    }

    //在图片中添加汉字
    public static byte[] addString(byte[] srcImage, Map<String, String> kv) throws Exception {
        BufferedImage image = byte2Image(srcImage);
        return addString(image, kv);
    }

    public static byte[] addString(BufferedImage image, Map<String, String> kv) throws Exception {
        if (image == null) {
            return null;
        }

        Graphics2D graphics = image.createGraphics();
        if (kv != null) {
            Set<String> positions = kv.keySet();
            for (String pos : positions) {
                String value = kv.get(pos);
                if (value == null) {
                    continue;
                }

                //s = x_y_sognti_style_frontSize_R_G_B
                String[] s = pos.split("_");
                int x = new Integer(s[0]);
                int y = new Integer(s[1]);
                graphics.setFont(getFont(s));
                graphics.setColor(getColor(s));
                graphics.drawString(value, x, y);
            }
        }
        //关闭画笔
        graphics.dispose();

        //输出最终的图形
        byte[] bytes = image2byte(image);

        return bytes;
    }

    //s = x_y_sognti_style_frontSize_R_G_B
    private static Color getColor(String[] s) {
        Color color = null;
        if (s != null && s.length <= 5) {
            color = Color.black;
        } else {
            Integer r = getValue(s, 5, new Integer(255));
            Integer g = getValue(s, 6, new Integer(255));
            Integer b = getValue(s, 7, new Integer(255));
            color = Color.getHSBColor(r, g, b);
        }
        return color;
    }

    //s = x_y_sognti_style_frontSize_R_G_B
    private static Font getFont(String[] s) {
        Font font = null;
        if (s != null && s.length <= 2) {
            font = new Font(DEFAULT_FONT, Font.PLAIN, 120);
        } else {
            String fontName = getValue(s, 2, DEFAULT_FONT);
            fontName = calcFontName(fontName);//不同系统可能不支持

            Integer frontStyle = getValue(s, 3, new Integer(1));//0,1,2  斜体,加粗
            Integer frontSize = getValue(s, 4, new Integer(120));
            //https://www.yzktw.com.cn/post/1503800.html
            font = new Font(fontName, frontStyle, frontSize);//宋体,雅黑,大小
        }
        return font;
    }

    //提取数组中的值
    private static <T> T getValue(String[] arr, int index, T defValue) {
        T res = null;
        if (arr == null || arr.length <= index) {
            return defValue;
        }
        try {
            String tmp = arr[index];
            if (StringUtils.isNotBlank(tmp)) {
                if (defValue instanceof String) {
                    res = (T) tmp;
                } else if (defValue instanceof Integer) {
                    res = (T) Integer.valueOf(tmp);
                } else if (defValue instanceof Long) {
                    res = (T) Long.valueOf(tmp);
                } else if (defValue instanceof Double) {
                    res = (T) Double.valueOf(tmp);

                } else if (defValue instanceof Float) {
                    res = (T) Float.valueOf(tmp);
                } else {
                    res = defValue;
                }
            } else {
                res = defValue;
            }
        } catch (Exception e) {
            res = defValue;
        }

        return res;
    }


    //获取key
    public static String getImageMapKey(Integer x, Integer y, String ziti, String style, Integer frontSize, Integer r, Integer g, Integer b) {
        StringBuffer sb = new StringBuffer();
        String t = "";
        if (x != null) {
            t += x;
        }
        sb.append(t + "_");

        t = "";
        if (y != null) {
            t += y;
        }
        sb.append(t + "_");

        t = "";
        if (StringUtils.isNotBlank(ziti)) {
            t += ziti;
        }
        sb.append(t + "_");

        t = "";
        if (StringUtils.isNotBlank(style)) {
            t += style;
        }
        sb.append(t + "_");

        t = "";
        if (frontSize != null) {
            t += frontSize;
        }
        sb.append(t + "_");

        t = "";
        if (r != null) {
            t += r;
        }
        sb.append(t + "_");

        t = "";
        if (g != null) {
            t += g;
        }
        sb.append(t + "_");

        t = "";
        if (b != null) {
            t += b;
        }

        return sb.toString();
    }

    //图片合并
    private static BufferedImage merge(BufferedImage image1, BufferedImage image2, boolean isHorizontal) {
        int h1 = image1.getHeight();
        int w1 = image1.getWidth();
        int h2 = image2.getHeight();
        int w2 = image2.getWidth();

        // 生成新图片
        BufferedImage newImage = null;
        if (isHorizontal) { // 水平方向合并
            int maxH = h1 > h2 ? h1 : h2;
            newImage = new BufferedImage(w1 + w2, maxH, BufferedImage.TYPE_INT_RGB);
            newImage.setRGB(0, 0, w1, h1, image2Int(image1), 0, w1); // 设置上半部分或左半部分的RGB
            newImage.setRGB(w1, 0, w2, h2, image2Int(image2), 0, w2);
        } else { // 垂直方向合并
            int maxW = w1 > w2 ? w1 : w2;
            newImage = new BufferedImage(maxW, h1 + h2, BufferedImage.TYPE_INT_RGB);
            newImage.setRGB(0, 0, w1, h1, image2Int(image1), 0, w1); // 设置上半部分或左半部分的RGB
            newImage.setRGB(0, h1, w2, h2, image2Int(image2), 0, w2); // 设置下半部分的RGB
        }

        return newImage;
    }

    // 字符串格式
    private static String image2Base64(BufferedImage image) {
        String encode = null;
        byte[] bytes = image2byte(image);
        if (bytes != null) {
            encode = Base64Util.encode(bytes);
        }
        return encode;
    }

    // base64转image
    private static BufferedImage base642Image(String base64) {
        BufferedImage image = null;
        byte[] decode = Base64Util.decode(base64);
        image = byte2Image(decode);
        return image;
    }

    // base64转image
    private static BufferedImage byte2Image(byte[] decode) {
        BufferedImage image = null;
        ByteArrayInputStream bais = null;
        try {
            bais = new ByteArrayInputStream(decode);
            image = ImageIO.read(bais);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return image;
    }

    // 字符数组格式
    private static byte[] image2byte(BufferedImage image) {
        byte[] bytes = null;
        if (image == null) {
            return bytes;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", baos);
            bytes = baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }

    // int数组格式
    private static int[] image2Int(BufferedImage image) {
        if (image == null) {
            return null;
        }

        int h1 = image.getHeight();
        int w1 = image.getWidth();
        int[] arr = new int[h1 * w1];

        //读取数据到arr中
        image.getRGB(0, 0, w1, h1, arr, 0, w1);
        return arr;
    }

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("40_200_宋体_1_60", "我喜： 欢你");
        String dir = "C:\\Users\\Administrator\\Pictures\\Saved Pictures";
        byte[] bytes = new byte[0];
        try {
            bytes = addString(dir + "\\c.png", map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        FileUtil.writeByte(dir + "\\a--.png", bytes);
    }
}
